pipe関数は、パイプを生成します。パイプとは、通常のファイルの入出力と同じような操作で、プロセス間でのデータのやりとりを行う仕組みです。
この関数は、C言語のライブラリ関数(標準関数)ではありませんので、コンパイラにより、使えない場合があります。
#include <unistd.h>
int pipe(int pipefd[2]);
pipefd[2]はパイプの両端を参照するファイル・ディスクリプタを格納する配列を指定します。
戻り値として、処理が成功した場合は0が、エラーの場合は-1を返します。
引数のpipefd[2]のpipefd[0]がパイプの読み出し側で、pipefd[1]がパイプの書き込み側です。例えば、親プロセスから子プロセスにデータを送る場合は、親プロセスはpipefd[1]を使ってデータを出力して、子プロセスはpipefd[0]を使ってデータを入力します。
プログラム 例
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#define BUFF_SIZE 1024
int main(int argc, char **argv)
{
int pipefd[2];
int p_id;
int status;
FILE *fp;
char buff[BUFF_SIZE];
if (argc != 2) {
fprintf(stderr, 'main : 実行時引数の数が不当です\n');
exit(EXIT_FAILURE);
}
if (pipe(pipefd) == -1) {
perror('main ');
exit(EXIT_FAILURE);
}
if ((p_id = fork()) == -1) {
perror('main ');
exit(EXIT_FAILURE);
}
if (p_id == 0) {
/* 子プロセス */
/* 使用しないwrite側はクローズ */
close(pipefd[1]);
/* パイプから読み込む */
while (read(pipefd[0], &buff, BUFF_SIZE) > 0) {
fputs(buff, stdout);
}
close(pipefd[0]);
}
else {
/* 親プロセス */
/* 使用しないread側はクローズ */
close(pipefd[0]);
if ((fp = fopen(*(argv + 1), 'r')) != NULL) {
while(fgets(buff, BUFF_SIZE, fp) != NULL) {
/* パイプに書き込む */
write(pipefd[1], buff, strlen(buff) + 1);
}
fclose(fp);
}
else {
perror('親プロセス ');
}
close(pipefd[1]);
wait(&status);
}
return EXIT_SUCCESS;
}
例の実行結果
$ cat temp_1.txt Hello World!!. Bye. $ $ ./pipe.exe temp_1.txt Hello World!!. Bye. $